package com.zxy.bilibili.old;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * BiliMerge 该类从其他地方借鉴过来，并修改过。由于代码写的不够优雅。自己重写了，参考MainApp
 * @author ZENG.XIAO.YAN
 * @Date 2020-08-08
 * @version 1.0
 */
@Deprecated
public class BiliMerge {
    private static List<BiliName> biliNameArrayList = new ArrayList<>();

    public static void main(String[] args) throws IOException {
        //bilibili视频缓存所在的文件夹,自动递归查找文件夹
        String inFile = "D:\\bilibili\\source\\93824064";
        //ffmpeg.exe 的所在目录
        String ffmpegFile = ("ffmpeg-4.3.1\\bin\\ffmpeg.exe");
        //输出目录  这里必须要是\\结尾
        String outFile = "D:\\bilibili\\target\\";

        long start = System.currentTimeMillis();
        runffmpeg(inFile, outFile, ffmpegFile);
        System.out.println("所用时间：" + (System.currentTimeMillis() - start));

    }

    public static void runffmpeg(String inFile, String outFile, String ffmpegFile) {
        fileName(new File(inFile));
        biliNameArrayList.stream().parallel()
                .filter(biliName -> !new File(new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString()).isFile())
                .forEach(biliName ->
                        {
                            if (StringUtils.isNotEmpty(biliName.getAudioFile()) && StringUtils.isNotEmpty(biliName.getVideoFile())) {
                                ffmpegUtil(biliName.getVideoFile(), biliName.getAudioFile(), new StringBuilder(outFile).append(biliName.getName()).append(".mp4").toString(),
                                        ffmpegFile);
                                System.out.println(biliName.getName() + ",转换成功");
                            } else {
                                if (null == biliName.getVideoFile()) {
                                    System.err.println("编号id为：" + biliName.getId() + " 输入的video.m4s 不存在" + ".详细信息为： " + biliName);
                                }
                                if (null == biliName.getAudioFile()) {
                                    System.err.println("编号id为：" + biliName.getId() + " 输入的audio.m4s 不存在" + ".详细信息为： " + biliName);
                                }
                            }
                        }
                );


    }



    public static void fileName(File file) {
        // 如果是文件夹
        if (file.isDirectory()) {
            String[] directoryList = file.list();
            // 子文件递归查询
            if (ArrayUtils.isNotEmpty(directoryList)) {
                for (String directory : directoryList) {
                    fileName(new File(file, directory));
                }
            }
        }
        // 如果是文件，则判断文件类型
        String fileName = file.getName();
        if (file.isFile()) {
            // entry.json
            if ("entry.json".equals(fileName)) {
                String id = file.getParentFile().getName();
                readerName(id, file);
            }
            if ("audio.m4s".equals(fileName) || "video.m4s".equals(fileName)) {
                // 如果是视频或者音频，则获取avid和
                File parentFile = parentName(file);
                Integer avId = Integer.valueOf(parentFile.getParentFile().getName());
                BiliName biliName = findBiliById(parentFile.getName(), avId);
                if ("audio.m4s".equals(fileName)) {
                    biliName.setAudioFile(file.getPath());
                }
                if ("video.m4s".equals(fileName)) {
                    biliName.setVideoFile(file.getPath());
                }
            }
        }
    }

    private static BiliName findBiliById(String id, Integer avId) {
        if (biliNameArrayList != null) {
            for (BiliName biliName : biliNameArrayList) {
                if (biliName != null && id.equals(biliName.getId()) && avId.equals(biliName.getAvid())) {
                    return biliName;
                }
            }
        }
        BiliName biliName = new BiliName();
        biliName.setId(id);
        biliName.setAvid(avId);
        biliNameArrayList.add(biliName);
        return biliName;
    }


    private static File parentName(File file) {
        return file.getParentFile().getParentFile();
    }

    private static void setName(String id, Integer avid, String parentName, String name) {
        if (biliNameArrayList != null) {
            for (BiliName biliName : biliNameArrayList) {
                if (biliName != null && id.equals(biliName.getId()) && avid.equals(biliName.getAvid())) {
                    biliName.setParentName(parentName);
                    biliName.setName(name);
                    biliName.setAvid(avid);
                    break;
                }
            }
        }
    }

    private static void readerName(String id, File file) {
        BufferedReader bufferedReader = null;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
            String jsonStr = sb.toString();
            Map map = JSON.parseObject(jsonStr, Map.class);
            if (map.containsKey("title") && map.containsKey("avid")) {
                String title = (String) map.get("title");
                Integer avid = (Integer) map.get("avid");
                if (map.containsKey("page_data")) {
                    JSONObject page_data = (JSONObject) map.get("page_data");
                    String fileName = (String)page_data.get("part");
                    setName(id, avid, title, fileName);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    private static void ffmpegUtil(String videoFile, String audioFile, String outFile, String FFmpeg) {
        if (videoFile == null || audioFile == null || outFile == null || FFmpeg == null) {
            return;
        } else {
            ProcessBuilder processBuilder = new ProcessBuilder();
            List<String> command = new ArrayList<>();
            command.add(FFmpeg);
            command.add("-i");
            command.add(videoFile);
            command.add("-i");
            command.add(audioFile);
            command.add("-codec");
            command.add("copy");
            command.add(outFile);
            processBuilder.command(command);
            processBuilder.redirectErrorStream(true);

//            InputStream inputStream = null;
            Process process = null;
            try {
                //启动进程
                process = processBuilder.start();
//                inputStream = process.getInputStream();
                //转成字符流
//                List biliNameArrayList = IOUtils.readLines(inputStream, "utf-8");
//                biliNameArrayList.stream().forEach(System.out::println);
            } catch (IOException e) {
                e.printStackTrace();
//            } finally {
//                IOUtils.closeQuietly(inputStream);
            }
        }
    }
}

@Deprecated
@Data
class BiliName {
    private String id;
    private String parentName;
    private String name;
    private String videoFile;
    private String audioFile;
    private Integer avid;
}

